/*
 * Copyright 2009 Vladimir Ritz Bossicard
 *
 * This file is part of OraDoc.
 *
 * OraDoc is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * Version     : $Revision: 18 $
 * Last edit   : $Date: 2009-03-17 21:33:05 +0000 (Tue, 17 Mar 2009) $
 * Last editor : $Author: vbossica@gmail.com $
 */
package org.oradoc;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.ProgressMonitor;

import net.miginfocom.swing.MigLayout;

import org.jdesktop.swingworker.SwingWorker;

/**
 * Swing Client.
 *
 * @author Vladimir Ritz Bossicard
 */
public class GeneratorSwing extends AbstractGeneratorApp {

	private final static int FIELD_SIZE = 30;

    private OradocTask task = null;;

    private ProgressMonitor progressMonitor;

	@Override
	protected void proceed(final String name, final String version, final String connection,
			final String username, final String password, final String outdir) throws Exception {
        new GeneratorSwing().createGUI(name, version, connection, username, password, outdir);
    }

    private void createGUI(final String name, final String version, final String connection, final String username, final String password, final String outdir) {
        final JFrame frame = new JFrame("OraDoc " + new Version().getVersion());
        MigLayout layout = new MigLayout();

        Container pane = frame.getContentPane();
        pane.setLayout(layout);

        pane.add(new JLabel("Project Information"), "span 2, wrap");
        pane.add(new JSeparator(), "span 2, growx, wrap");
        pane.add(new JLabel("  name: "));
        final JTextField nameField = new JTextField(name, FIELD_SIZE);
        pane.add(nameField, "growx, wrap");
        pane.add(new JLabel("  version: "));
        final JTextField versionField = new JTextField(version, FIELD_SIZE);
        pane.add(versionField, "growx, wrap");

        pane.add(new JLabel("Database Information"), "span 2, wrap");
        pane.add(new JSeparator(), "span 2, growx, wrap");
        pane.add(new JLabel("  connection: "));
        final JTextField connectionField = new JTextField(connection, FIELD_SIZE);
        pane.add(connectionField, "growx, wrap");
        pane.add(new JLabel("  username: "));
        final JTextField usernameField = new JTextField(username, FIELD_SIZE);
        pane.add(usernameField, "growx, wrap");
        pane.add(new JLabel("  password: "));
        final JPasswordField passwordField = new JPasswordField(password, FIELD_SIZE);
        pane.add(passwordField, "growx, wrap");

        pane.add(new JLabel("Output"), "span 2, wrap");
        pane.add(new JSeparator(), "span 2, growx, wrap");
        pane.add(new JLabel("  directory: "));
        final JTextField outdirField = new JTextField(outdir, FIELD_SIZE);
        pane.add(outdirField, "growx, wrap");

        final JButton processButton = new JButton("process");
        processButton.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
				try {
					GeneratorSwing.this.progressMonitor = new ProgressMonitor(frame, "Processing", "", 0, 100);
					GeneratorSwing.this.progressMonitor.setProgress(0);
					GeneratorSwing.this.progressMonitor.setMillisToDecideToPopup(0);

					GeneratorSwing.this.task = new OradocTask(nameField.getText(), versionField.getText(), outdirField.getText(), connectionField.getText(), passwordField.getPassword(), usernameField.getText());
					GeneratorSwing.this.task.addPropertyChangeListener(new PropertyChangeListener() {
						public void propertyChange(final PropertyChangeEvent evt) {
							if ("progress" == evt.getPropertyName()) {
								int progress = (Integer) evt.getNewValue();
								GeneratorSwing.this.progressMonitor.setProgress(progress);
//								String message = String.format("Completed %d%%.\n", progress);
//								progressMonitor.setNote(message);
								if (GeneratorSwing.this.progressMonitor.isCanceled() || GeneratorSwing.this.task.isDone()) {
									if (GeneratorSwing.this.progressMonitor.isCanceled()) {
										GeneratorSwing.this.task.cancel(true);
										System.out.println("Task canceled.\n");
									} else {
										System.out.println("Task completed.\n");
									}
									processButton.setEnabled(true);
								}
							}
						}
					});
					GeneratorSwing.this.task.execute();

				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}

		});
        pane.add(processButton, "span 2, right");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    private final class OradocTask extends SwingWorker<Void, Void> {

    	private String name, version, outdir, connection, username;
    	char[] password;

		public OradocTask(final String name, final String version, final String outdir,
				final String connection, final char[] password, final String username) {
			this.name = name;
			this.version = version;
			this.outdir = outdir;
			this.connection = connection;
			this.password = password;
			this.username = username;
		}

		@Override
        public Void doInBackground() {
			try {
				Generator documenter = new Generator();
		    	documenter.setProperty("project.name", this.name);
		    	documenter.setProperty("project.version", this.version);
				documenter.setProperty("outdir", this.outdir);
		        documenter.setProperty("oradoc.connection", this.connection);
		        documenter.setProperty("oradoc.username", this.username);
		        documenter.setProperty("oradoc.password", String.valueOf(this.password));

				documenter.init("org.oradoc.config.DefaultConfig", new ProcessListener() {

					public void start() {
			            setProgress(0);
					}

					public void finished() {
			            setProgress(100);
					}

					public void info(final String message) {
						GeneratorSwing.this.progressMonitor.setNote(message);
					}

					public void step(final int current, final int max, final String message) {
						int progress = (int) Math.min((long) current * 100 / max, 100);
						setProgress(progress);
						GeneratorSwing.this.progressMonitor.setNote(message);
					}

				});
				documenter.process();
			} catch (Exception ex) {
				System.err.println("exception caught " + ex.getMessage());
			}
			// documenter.process(nameField.getText(),
			// versionField.getText(), connectionField.getText(),
			// usernameField.getText(), passwordField.getPassword(), new
			// File(outdirField.getText()));


//            Random random = new Random();
//            int progress = 0;
//            setProgress(0);
//            try {
//                Thread.sleep(1000);
//                while (progress < 100 && !isCancelled()) {
//                    //Sleep for up to one second.
//                    Thread.sleep(random.nextInt(1000));
//                    //Make random progress.
//                    progress += random.nextInt(10);
//                    setProgress(Math.min(progress, 100));
//                }
//            } catch (InterruptedException ignore) {}
            return null;
        }

        @Override
        public void done() {
            // processButton.setEnabled(true);
            GeneratorSwing.this.progressMonitor.setProgress(0);
        }
    }

	@Override
	protected boolean areArgsRequired() {
		return false;
	}

    public static void main(final String[] args) {
    	new GeneratorSwing().start(args);
    }

}
